Hypothesis Tests on Audio Features

Two sample - independent tests

This is an example of the hypothesis tests which were carried out on each audio feature.

H0: The mean danceability in 1960s is the same as the mean danceability in 2010s

Ha: The mean danceability in 1960s is less than the mean danceability in 2010s

H0: The difference in means in 0 Ha: danceability2020 - danceability1960 > 0

How do the audio features change over time

spotify_data_clean_pivot <- spotify_data_clean_join %>% 
  pivot_longer(cols = acousticness:valence,
              names_to = "audio_feature",
              values_to = "value") %>% 
  group_by(year, audio_feature) %>% 
  mutate(avg_feature = mean(value))

Plot with all Audio Features

Plot with audio features showing change

spotify_data_clean_join %>% 
  #mutate(explicit = as.numeric(explicit)) %>% 
  group_by(year) %>% 
  summarise(total_ex = sum(explicit)) %>% 
  ggplot() +
  aes(x = year, y = total_ex / 20) +
  geom_line(colour = "red", linewidth = 2) +
  ylim(0, 50) +
  labs(x = "Year",
       y = "Proportion")+
       # title = "Proportion of Explicit Songs",
       # subtitle = "by year") +
  theme_classic() +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 22, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 14, family = "Times"),
        legend.title = element_blank()
  ) 

ggsave("plot_images/explicit.png", dpi = 720, width = 10, height = 6)

spotify_data_clean_join %>% 
  group_by(year) %>% 
  summarise(mean_pop = mean(popularity)) %>% 
  ggplot() +
  aes(x = year, y = mean_pop) +
  geom_line(colour = "purple2", linewidth = 2) +
  labs(x = "Year",
       y = "Popularity") +
  ylim(0, 100) +
  theme_bw() +
  scale_colour_brewer(palette =  "Dark2") +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 22, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 14, family = "Times")
  ) 

ggsave("plot_images/avg_pop.png", dpi = 720, width = 10, height = 6)

spot_sample %>% 
  ggplot() +
  aes(x = danceability, y = popularity) +
  geom_point(colour = "#1DB954", alpha = 0.8) +
  geom_smooth(method = "lm", se = FALSE, colour = "purple3", linewidth = 2) +
  labs(x = "Danceability",
       y = "Popularity") +
       theme_classic() +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 20, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 14, family = "Times")
  )


#ggsave("plot_images/pop_vs_dance.png", dpi = 720, width = 10, height = 6)
spot_sample %>% 
  ggplot() +
  aes(x = loudness, y = popularity) +
  geom_point(colour = "#1DB954", alpha = 0.6) +
  geom_smooth(method = "lm", se = FALSE, colour = "purple3", linewidth = 2) +
  labs(x = "Loudness",
       y = "Popularity") +
       theme_classic() +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 22, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 14, family = "Times")
  )

ggsave("plot_images/pop_vs_loud.png", dpi = 720, width = 10, height = 6)

Intro To Linear Regression

To help me answer my question of what makes a song “popular” on spotify, I decided to build an explanatory linear regression model.

This type of analysis is used to determine the strength of the relationship between a response variable and multiple explanatory variables.

So in this case I will be choosing from all of the variables I have just discussed to explain the popularity of a song on spotify.

y = b0 + b1x1 + b2x2 + b3x3….bnxn

popularity = b0 + b1x1 + b2x2 + b3x3….bnxn

To start this process I plot popularity against each one of my variables or possible explanatory variables and find the strongest correlation.

n_data <- nrow(spotify_data_for_modelling)

sample_index <- sample(1:n_data, size = n_data*0.1)

spot_sample <- slice(spotify_data_for_modelling, sample_index)

spot_sample %>% 
  ggplot() +
  aes(x = year, y = popularity) +
  geom_point(alpha = 0.7, colour = "#1DB954") +
  geom_smooth(method = "lm", se = FALSE, colour = "purple2") +
  theme_classic() +
  labs(x = "Year",
       y = "Popularity") +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 18, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 14, family = "Times")
  )


#ggsave("plot_images/pop_vs_dance.png", dpi = 720, width = 10, height = 6)
spot_sample %>% 
  ggplot() +
  aes(x = explicit, y = popularity) +
  geom_point(alpha = 0.7, colour = "red4") +
  geom_smooth(method = "lm", se = FALSE)

My strongest correlation was year (the year the track was released) with a correlation of 0.74. I then add this to my model as my first explanatory variable.

model_1a <- lm(popularity ~ year,
               data = train_lm)

summary(model_1a)

Call:
lm(formula = popularity ~ year, data = train_lm)

Residuals:
    Min      1Q  Median      3Q     Max 
-19.600  -7.447  -1.773   5.668  54.400 

Coefficients:
                Estimate   Std. Error t value            Pr(>|t|)    
(Intercept) -1220.936768     3.742482  -326.2 <0.0000000000000002 ***
year            0.634644     0.001881   337.4 <0.0000000000000002 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 10.08 on 95918 degrees of freedom
Multiple R-squared:  0.5427,    Adjusted R-squared:  0.5427 
F-statistic: 1.138e+05 on 1 and 95918 DF,  p-value: < 0.00000000000000022

After running my model I’m looking at 3 factors: - The P-value - is this variable making a significant difference. If the P-value is below the significance level of 0.05 then we can reject the null hypothesis and conclude that correlation between the variables is significant

  • The R^2 - is a measure that indicates how much of the variation of popularity is explained by the year
  • The adjusted R^2 - compensates for the addition of variables. So as we’re building an explanatory model, we don’t want this to drop much lower than the r^2.
model_3a <- lm(popularity ~ year + danceability + loudness,
               data = train_lm)

summary(model_3a)
model_3b <- lm(popularity ~ year + danceability + instrumentalness,
               data = train_lm)

summary(model_3b)
anova(model_3a, model_2c)

Final Model

So here we have our final model. I stopped adding variables as the Adjusted r^2 started dropping and our multiple r^2 was barely going up.

So we can see that the more recent the release, the more danceability, the louder it is, the less liveness it has. So you don’t want a live recording, you want a studio recording with some explicit lyrics chucked in there as well.

All of our P-Values are significant and we have a Multiple r^2 of 0.55, with an adjusted r^2 also of 0.55. This means that 55% of the variance in popularity is explained our other variables. Which also means that 45% of the variability in the data cannot be explained by this model.

55% isn’t a very high proportion but it’s not terrible. We are trying to measure the popularity of a song. It’s not quite as obvious as if we were trying to explain the value of a house. We might find that the postcode and the number of rooms goes a long way to explaining that value. I think explaining the popularity of a song is bit more complicated than that. If it was easy to know what made a song popular then we’d all be musicians.

Mention human behaviour, mention the basic practice of statistics would call this a moderate effect size.

So my model isn’t great. What can I do to improve this? Well…

When I was researching how spotify calculate their popularity score I kept coming across this one phrase.

50 is the magic number

The higher your popularity index, the more likely the algorithm is to recommend you to new listeners, and place you in algorithmic playlists like Release Radar and Discover Weekly. Many websites and blogs had theories on what number you had to hit to be added to certain editorial playlists.

DIYMusician suggests that and popularity of 20+ in the first few weeks of release will get you onto the Release Radar playlist and a popularity score of 30+ will get you onto Discover Weekly. Loudlab suggested that 50 is the magic number. I liked this idea of having a threshold of whether or not a song is popular. So going back to my variables I created a column called is_popular which is only TRUE if the popularity of the song is 50 or over. This also lends itself nicely to a logistic regression model.

Logistic regression is a statistical analysis method to predict, or explain a binary outcome, such as yes or no, based on prior observations of a data set.

So rather than using the popularity score I have used the variable I created called is_popular, which splits the data in to a logical type, so it’s TRUE if the song is 50 or above.

The way this is built is very similar to the linear model. I look for correlations, and I add them to my model 1 at a time, check they are significant. The main difference is that I’m looking for for a high AUC score this time, rather than the multiple r^squared I was looking for in the linear model.

I’ll explain the AUC in a second. I decided for this model to make a couple of changes. I decided to no longer include the year or decade the song was released. If I’m staying true to my original question then how could I possibly write a song that was released in the past. It had such a large influence on the linear model I thought it would be more interesting to see how the logistic model fared without it. And then I can test my model against different decades to see how it performs.

Oscar Wilde is famously credited with having written: “Popularity is the one insult I have never suffered.”

spot_sample %>% 
  mutate(explicit = as.logical(explicit)) %>% 
  ggplot() +
  aes(x = loudness, y = popularity, colour = explicit) +
  geom_point(alpha = 0.8) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(x = "Loudness",
       y = "Popularity",
       title = "Relationship between Popularity and Loundess",
       subtitle = "Grouped by explicit or not") +
    scale_colour_brewer(palette =  "Dark2") +
  theme_bw() +
  theme(axis.text  = element_text(face = "bold", size = 15, family = "Times"),
        axis.title  = element_text(face = "bold", size = 15, family = "Times"),
        title = element_text(face = "bold", size = 15, family = "Times"),
        legend.text = element_text(face = "bold", size = 10, family = "Times")
  ) 

spot_sample %>% 
  mutate(explicit = as.logical(explicit)) %>%
ggplot() +
  aes(x = loudness, y = as.integer(is_popular), colour = explicit) +
  geom_jitter(shape = 1,
              position = position_jitter(h = 0.05, w = 0.05),
              alpha = 0.8) +
   geom_line(data = train_model_1_loud, aes(x = loudness , y = pred), col = 'red') +
  ylab("Probability") +
      scale_colour_brewer(palette =  "Dark2") +
  theme_bw() +
  theme(axis.text  = element_text(face = "bold", size = 15, family = "Times"),
        axis.title  = element_text(face = "bold", size = 15, family = "Times"),
        title = element_text(face = "bold", size = 15, family = "Times"),
        legend.text = element_text(face = "bold", size = 10, family = "Times")
  ) 



# ggplot(mortgage_data) +
#   geom_jitter(aes(x = tu_score, y = as.integer(accepted)), shape = 1, 
#               position = position_jitter(h = 0.03)) + 
#    geom_line(data = predict_log, aes(x = tu_score , y = pred), col = 'red') + 
#   ylab("Probability")

Final Logistic Regression Model

model_4_final <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
             family = "binomial",
             data = train_log_mod)

summary(model_4_final)

Call:
glm(formula = is_popular ~ loudness + explicit + danceability + 
    no_of_artists, family = "binomial", data = train_log_mod)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-2.3012  -0.8550  -0.6624   1.1355   3.7138  

Coefficients:
                Estimate Std. Error z value            Pr(>|z|)    
(Intercept)   -7.7547047  0.0993408  -78.06 <0.0000000000000002 ***
loudness       0.0780446  0.0012231   63.81 <0.0000000000000002 ***
explicit       1.0409331  0.0237662   43.80 <0.0000000000000002 ***
danceability   0.0095757  0.0004548   21.06 <0.0000000000000002 ***
no_of_artists  0.1844060  0.0114087   16.16 <0.0000000000000002 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 121164  on 97324  degrees of freedom
Residual deviance: 110272  on 97320  degrees of freedom
AIC: 110282

Number of Fisher Scoring iterations: 4
tidy(model_4_final)

train_model_4_final <- train_log_mod %>%
  add_predictions(model_4_final, type = "response")

roc_obj_mod4 <- train_model_4_final %>%
  roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
  data = list(
    best_model = roc_obj_mod4
  ), 
  legacy.axes = TRUE) +
  coord_fixed() + 
  theme_classic()

auc(roc_obj_mod4)
Area under the curve: 0.7223
log_mod_1990 <- train_log_mod %>% 
  filter(decade == 1990 |
           decade == 2000 |
           decade == 2010)

model_90_00_10 <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
                      family = "binomial",
                      data = log_mod_1990)

summary(model_90_00_10)

Call:
glm(formula = is_popular ~ loudness + explicit + danceability + 
    no_of_artists, family = "binomial", data = log_mod_1990)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-2.2496  -1.1659   0.8386   1.1431   2.3491  

Coefficients:
                Estimate Std. Error z value             Pr(>|z|)    
(Intercept)   -3.1595029  0.1137598 -27.773 < 0.0000000000000002 ***
loudness       0.0342887  0.0014178  24.185 < 0.0000000000000002 ***
explicit       0.4662174  0.0258787  18.016 < 0.0000000000000002 ***
danceability   0.0031530  0.0005672   5.559         0.0000000271 ***
no_of_artists  0.1691662  0.0143345  11.801 < 0.0000000000000002 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 66344  on 47879  degrees of freedom
Residual deviance: 64758  on 47875  degrees of freedom
AIC: 64768

Number of Fisher Scoring iterations: 4
tidy(model_90_00_10)

train_model_90_00_10 <- log_mod_1990 %>%
  add_predictions(model_90_00_10, type = "response")

roc_obj_mod_90_00_10 <- train_model_90_00_10 %>%
  roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
  data = list(
    best_model = roc_obj_mod4,
    dec_60s_70s_80s = roc_obj_mod_60_70_80,
    dec_90s_00s_10s = roc_obj_mod_90_00_10
  ), 
  legacy.axes = TRUE,
  linewidth = 2) +
  coord_fixed() +
  labs(x = "1 - Specificity",
       y = "Sensitivity") +
  scale_colour_brewer(palette =  "Dark2") +
  scale_colour_discrete(labels = c("Final Model", "60s, 70s & 80s", "90s, 00s & 10s")) +
  theme_classic() +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 18, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 18, family = "Times"),
        #legend.text = element_blank(),
        legend.title = element_blank()
        #legend.key = element_blank()
  )
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
auc(roc_obj_mod_90_00_10)
Area under the curve: 0.629
roc_curve

ggsave("plot_images/log_models.png", dpi = 720, width = 12, height = 6)


log_mod_1990 <- train_log_mod %>% 
  filter(decade == 1990 |
           decade == 2000 |
           decade == 2010)

model_90_00_10 <- glm(is_popular ~ loudness + explicit + danceability + no_of_artists,
                      family = "binomial",
                      data = log_mod_1990)

summary(model_90_00_10)

Call:
glm(formula = is_popular ~ loudness + explicit + danceability + 
    no_of_artists, family = "binomial", data = log_mod_1990)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-2.2496  -1.1659   0.8386   1.1431   2.3491  

Coefficients:
                Estimate Std. Error z value             Pr(>|z|)    
(Intercept)   -3.1595029  0.1137598 -27.773 < 0.0000000000000002 ***
loudness       0.0342887  0.0014178  24.185 < 0.0000000000000002 ***
explicit       0.4662174  0.0258787  18.016 < 0.0000000000000002 ***
danceability   0.0031530  0.0005672   5.559         0.0000000271 ***
no_of_artists  0.1691662  0.0143345  11.801 < 0.0000000000000002 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 66344  on 47879  degrees of freedom
Residual deviance: 64758  on 47875  degrees of freedom
AIC: 64768

Number of Fisher Scoring iterations: 4
tidy(model_90_00_10)

train_model_90_00_10 <- log_mod_1990 %>%
  add_predictions(model_90_00_10, type = "response")

roc_obj_mod_90_00_10 <- train_model_90_00_10 %>%
  roc(response = is_popular, predictor = pred)
Setting levels: control = FALSE, case = TRUE
Setting direction: controls < cases
roc_curve <- ggroc(
  data = list(
    best_model = roc_obj_mod4
  ), 
  legacy.axes = TRUE,
  linewidth = 2) +
  coord_fixed() +
  labs(x = "1 - Specificity",
       y = "Sensitivity") +
  scale_colour_brewer(palette =  "Dark2") +
  scale_colour_discrete(labels = "Final Model") +
  theme_classic() +
  theme(axis.text  = element_text(face = "bold", size = 18, family = "Times"),
        axis.title  = element_text(face = "bold", size = 18, family = "Times"),
        title = element_text(face = "bold", size = 18, family = "Times"),
        legend.text = element_text(face = "bold", size = 16, family = "Times"),
        legend.title = element_blank()
  )
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
auc(roc_obj_mod_90_00_10)
Area under the curve: 0.629
roc_curve

ggsave("plot_images/log_best_model.png", dpi = 720, width = 12, height = 6)

LS0tCnRpdGxlOiAiU3BvdGlmeSBBbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShzcG90aWZ5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobW9kZWxyKQpsaWJyYXJ5KGluZmVyKQpsaWJyYXJ5KG1vZGVscikKbGlicmFyeShnZ2ZvcnRpZnkpCmxpYnJhcnkoR0dhbGx5KQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnNwb3RpZnlfZGF0YV9jbGVhbl9qb2luIDwtIHJlYWRfY3N2KCJjbGVhbl9kYXRhL3Nwb3RpZnlfY2xlYW5fam9pbi5jc3YiKQpzcG90aWZ5X2RhdGEgPC0gcmVhZF9jc3YoInJhd19kYXRhL3Nwb3RpZnlfZGF0YS5jc3YiKQpgYGAKCgojIyBIeXBvdGhlc2lzIFRlc3RzIG9uIEF1ZGlvIEZlYXR1cmVzCgpUd28gc2FtcGxlIC0gaW5kZXBlbmRlbnQgdGVzdHMKClRoaXMgaXMgYW4gZXhhbXBsZSBvZiB0aGUgaHlwb3RoZXNpcyB0ZXN0cyB3aGljaCB3ZXJlIGNhcnJpZWQgb3V0IG9uIGVhY2ggYXVkaW8gZmVhdHVyZS4KCkgwOiBUaGUgbWVhbiBkYW5jZWFiaWxpdHkgaW4gMTk2MHMgaXMgdGhlIHNhbWUgYXMgdGhlIG1lYW4gZGFuY2VhYmlsaXR5IGluIDIwMTBzCgpIYTogVGhlIG1lYW4gZGFuY2VhYmlsaXR5IGluIDE5NjBzIGlzIGxlc3MgdGhhbiB0aGUgbWVhbiBkYW5jZWFiaWxpdHkgaW4gMjAxMHMKCkgwOiBUaGUgZGlmZmVyZW5jZSBpbiBtZWFucyBpbiAwCkhhOiBkYW5jZWFiaWxpdHkyMDIwIC0gZGFuY2VhYmlsaXR5MTk2MCA+IDAKYGBge3IgaW5jbHVkZT1GQUxTRX0KZGFuY2VfZGVjYWRlX2h5cCA8LSBzcG90aWZ5X2RhdGFfY2xlYW5fam9pbiAlPiUgCiAgc2VsZWN0KGRlY2FkZSwgZGFuY2VhYmlsaXR5KSAlPiUgCiAgZmlsdGVyKGRlY2FkZSA9PSAxOTYwIHwgZGVjYWRlID09IDIwMTApICU+JSAKICBtdXRhdGUoZGVjYWRlID0gYXMuZmFjdG9yKGRlY2FkZSkpCgpudWxsX2Rpc3RyaWJ1dGlvbiA8LSBkYW5jZV9kZWNhZGVfaHlwICU+JSAKICBzcGVjaWZ5KGRhbmNlYWJpbGl0eSB+IGRlY2FkZSkgJT4lIAogIGh5cG90aGVzaXplKG51bGwgPSAiaW5kZXBlbmRlbmNlIikgJT4lIAogIGdlbmVyYXRlKHJlcHMgPSA1MDAwLCB0eXBlID0gInBlcm11dGUiKSAlPiUgCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygiMjAxMCIsICIxOTYwIikpIAoKb2JzZXJ2ZWRfc3RhdCA8LSBkYW5jZV9kZWNhZGVfaHlwICU+JSAKICBzcGVjaWZ5KGRhbmNlYWJpbGl0eSB+IGRlY2FkZSkgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygiMjAxMCIsICIxOTYwIikpCgpudWxsX2Rpc3RyaWJ1dGlvbiAlPiUKICB2aXN1YWxpc2UoKSArCiAgc2hhZGVfcF92YWx1ZShvYnNfc3RhdCA9IG9ic2VydmVkX3N0YXQsIGRpcmVjdGlvbiA9ICJyaWdodCIpCgpwX3ZhbHVlIDwtIG51bGxfZGlzdHJpYnV0aW9uICU+JQogIGdldF9wX3ZhbHVlKG9ic19zdGF0ID0gb2JzZXJ2ZWRfc3RhdCwgZGlyZWN0aW9uID0gInJpZ2h0IikKYGBgCgojIyMgSG93IGRvIHRoZSBhdWRpbyBmZWF0dXJlcyBjaGFuZ2Ugb3ZlciB0aW1lCgpgYGB7cn0Kc3BvdGlmeV9kYXRhX2NsZWFuX3Bpdm90IDwtIHNwb3RpZnlfZGF0YV9jbGVhbl9qb2luICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGFjb3VzdGljbmVzczp2YWxlbmNlLAogICAgICAgICAgICAgIG5hbWVzX3RvID0gImF1ZGlvX2ZlYXR1cmUiLAogICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JSAKICBncm91cF9ieSh5ZWFyLCBhdWRpb19mZWF0dXJlKSAlPiUgCiAgbXV0YXRlKGF2Z19mZWF0dXJlID0gbWVhbih2YWx1ZSkpCmBgYAoKClBsb3Qgd2l0aCBhbGwgQXVkaW8gRmVhdHVyZXMKYGBge3J9CmF1ZGlvdF9mZWF0dXJlc19hbGwgPC0gc3BvdGlmeV9kYXRhX2NsZWFuX3Bpdm90ICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHllYXIsIHkgPSBhdmdfZmVhdHVyZSwgZ3JvdXAgPSBhdWRpb19mZWF0dXJlLCAKICAgICAgY29sb3VyID0gYXVkaW9fZmVhdHVyZSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAyKSArCiAgeWxpbSgwLCAxMDApICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIlZhbHVlIiwKICAgICAgIHRpdGxlID0gIkF1ZGlvIEZlYXR1cmVzIE92ZXIgVGltZSIsCiAgICAgICBzdWJ0aXRsZSA9ICJBdmcgcGVyIHllYXIiLAogICAgICAgY29sb3VyID0gIkF1ZGlvIEZlYXR1cmUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gICJEYXJrMiIpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgZmFtaWx5ID0gIlRpbWVzIikKICApIAoKI2dnc2F2ZShhdWRpb3RfZmVhdHVyZXNfYWxsLCAicGxvdF9pbWFnZXMvYXVkaW9fZmVhdHVyZXNfYWxsLnBuZyIpCmBgYAoKUGxvdCB3aXRoIGF1ZGlvIGZlYXR1cmVzIHNob3dpbmcgY2hhbmdlCmBgYHtyfQphdWRpb19mZWF0dXJlc19jdXQgPC0gc3BvdGlmeV9kYXRhX2NsZWFuX3Bpdm90ICU+JQogICAgZmlsdGVyKGF1ZGlvX2ZlYXR1cmUgPT0gImFjb3VzdGljbmVzcyIgfAogICAgICAgICAgIGF1ZGlvX2ZlYXR1cmUgPT0gImluc3RydW1lbnRhbG5lc3MiIHwKICAgICAgICAgICBhdWRpb19mZWF0dXJlID09ICJkYW5jZWFiaWxpdHkiIHwKICAgICAgICAgICBhdWRpb19mZWF0dXJlID09ICJzcGVlY2hpbmVzcyIgfAogICAgICAgICAgIGF1ZGlvX2ZlYXR1cmUgPT0gImxvdWRuZXNzIikgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IHllYXIsIHkgPSBhdmdfZmVhdHVyZSwgZ3JvdXAgPSBhdWRpb19mZWF0dXJlLCAKICAgICAgY29sb3VyID0gYXVkaW9fZmVhdHVyZSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAyKSArCiAgeWxpbSgwLCAxMDApICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIlZhbHVlIiwKICAgICAgICMgdGl0bGUgPSAiQXVkaW8gRmVhdHVyZXMgYnkgUmVsZWFzZSBZZWFyIiwKICAgICAgICMgc3VidGl0bGUgPSAiQXZnIHBlciB5ZWFyIiwKICAgICAgIGNvbG91ciA9ICJBdWRpbyBGZWF0dXJlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgc2NhbGVfY29sb3VyX2Rpc2NyZXRlKGxhYmVscyA9IGMoIkFjb3VzdGljbmVzcyIsICJEYW5jZWFiaWxpdHkiLCAiSW5zdHJ1bWVudGFsbmVzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxvdWRuZXNzIiwgIlNwZWVjaGluZXNzIikpICsKCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjAsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAyMiwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjAsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKQogICkgCgpnZ3NhdmUoInBsb3RfaW1hZ2VzL2F1ZGlvX2ZlYXR1cmVzX2N1dC5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTIsIGhlaWdodCA9IDYpCgo/Z2dzYXZlCmBgYAoKYGBge3J9CnNwb3RpZnlfZGF0YV9jbGVhbl9qb2luICU+JSAKICAjbXV0YXRlKGV4cGxpY2l0ID0gYXMubnVtZXJpYyhleHBsaWNpdCkpICU+JSAKICBncm91cF9ieSh5ZWFyKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsX2V4ID0gc3VtKGV4cGxpY2l0KSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IHllYXIsIHkgPSB0b3RhbF9leCAvIDIwKSArCiAgZ2VvbV9saW5lKGNvbG91ciA9ICJyZWQiLCBsaW5ld2lkdGggPSAyKSArCiAgeWxpbSgwLCA1MCkgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIpKwogICAgICAgIyB0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIEV4cGxpY2l0IFNvbmdzIiwKICAgICAgICMgc3VidGl0bGUgPSAiYnkgeWVhciIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjIsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0LCBmYW1pbHkgPSAiVGltZXMiKQogICkgCgpnZ3NhdmUoInBsb3RfaW1hZ2VzL2V4cGxpY2l0LnBuZyIsIGRwaSA9IDcyMCwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikKYGBgCmBgYHtyfQpzcG90aWZ5X2RhdGFfY2xlYW5fam9pbiAlPiUgCiAgZ3JvdXBfYnkoeWVhcikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BvcCA9IG1lYW4ocG9wdWxhcml0eSkpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gbWVhbl9wb3ApICsKICBnZW9tX2xpbmUoY29sb3VyID0gInB1cnBsZTIiLCBsaW5ld2lkdGggPSAyKSArCiAgbGFicyh4ID0gIlllYXIiLAogICAgICAgeSA9ICJQb3B1bGFyaXR5IikgKwogIHlsaW0oMCwgMTAwKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gICJEYXJrMiIpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDIyLCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgZmFtaWx5ID0gIlRpbWVzIikKICApIAoKZ2dzYXZlKCJwbG90X2ltYWdlcy9hdmdfcG9wLnBuZyIsIGRwaSA9IDcyMCwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikKCmBgYAoKYGBge3J9CnNwb3Rfc2FtcGxlICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBkYW5jZWFiaWxpdHksIHkgPSBwb3B1bGFyaXR5KSArCiAgZ2VvbV9wb2ludChjb2xvdXIgPSAiIzFEQjk1NCIsIGFscGhhID0gMC44KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gInB1cnBsZTMiLCBsaW5ld2lkdGggPSAyKSArCiAgbGFicyh4ID0gIkRhbmNlYWJpbGl0eSIsCiAgICAgICB5ID0gIlBvcHVsYXJpdHkiKSArCiAgICAgICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMjAsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0LCBmYW1pbHkgPSAiVGltZXMiKQogICkKCiNnZ3NhdmUoInBsb3RfaW1hZ2VzL3BvcF92c19kYW5jZS5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCgpgYGAKCmBgYHtyfQpzcG90X3NhbXBsZSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbG91ZG5lc3MsIHkgPSBwb3B1bGFyaXR5KSArCiAgZ2VvbV9wb2ludChjb2xvdXIgPSAiIzFEQjk1NCIsIGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gInB1cnBsZTMiLCBsaW5ld2lkdGggPSAyKSArCiAgbGFicyh4ID0gIkxvdWRuZXNzIiwKICAgICAgIHkgPSAiUG9wdWxhcml0eSIpICsKICAgICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAyMiwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGZhbWlseSA9ICJUaW1lcyIpCiAgKQoKZ2dzYXZlKCJwbG90X2ltYWdlcy9wb3BfdnNfbG91ZC5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCgpgYGAKCiMjIyBJbnRybyBUbyBMaW5lYXIgUmVncmVzc2lvbgoKVG8gaGVscCBtZSBhbnN3ZXIgbXkgcXVlc3Rpb24gb2Ygd2hhdCBtYWtlcyBhIHNvbmcgInBvcHVsYXIiIG9uIHNwb3RpZnksIEkgZGVjaWRlZCB0byBidWlsZCBhbiBleHBsYW5hdG9yeSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbC4gCgpUaGlzIHR5cGUgb2YgYW5hbHlzaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0cmVuZ3RoIG9mIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhIHJlc3BvbnNlIHZhcmlhYmxlIGFuZCBtdWx0aXBsZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMuCgpTbyBpbiB0aGlzIGNhc2UgSSB3aWxsIGJlIGNob29zaW5nIGZyb20gYWxsIG9mIHRoZSB2YXJpYWJsZXMgSSBoYXZlIGp1c3QgZGlzY3Vzc2VkIHRvIGV4cGxhaW4gdGhlIHBvcHVsYXJpdHkgb2YgYSBzb25nIG9uIHNwb3RpZnkuCgp5ID0gYjAgKyBiMXgxICsgYjJ4MiArIGIzeDMuLi4uYm54bgoKcG9wdWxhcml0eSA9IGIwICsgYjF4MSArIGIyeDIgKyBiM3gzLi4uLmJueG4KClRvIHN0YXJ0IHRoaXMgcHJvY2VzcyBJIHBsb3QgcG9wdWxhcml0eSBhZ2FpbnN0IGVhY2ggb25lIG9mIG15IHZhcmlhYmxlcyBvciBwb3NzaWJsZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYW5kIGZpbmQgdGhlIHN0cm9uZ2VzdCBjb3JyZWxhdGlvbi4KCmBgYHtyfQpuX2RhdGEgPC0gbnJvdyhzcG90aWZ5X2RhdGFfZm9yX21vZGVsbGluZykKCnNhbXBsZV9pbmRleCA8LSBzYW1wbGUoMTpuX2RhdGEsIHNpemUgPSBuX2RhdGEqMC4xKQoKc3BvdF9zYW1wbGUgPC0gc2xpY2Uoc3BvdGlmeV9kYXRhX2Zvcl9tb2RlbGxpbmcsIHNhbXBsZV9pbmRleCkKCnNwb3Rfc2FtcGxlICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSB5ZWFyLCB5ID0gcG9wdWxhcml0eSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIGNvbG91ciA9ICIjMURCOTU0IikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG91ciA9ICJwdXJwbGUyIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIlllYXIiLAogICAgICAgeSA9ICJQb3B1bGFyaXR5IikgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0LCBmYW1pbHkgPSAiVGltZXMiKQogICkKCiNnZ3NhdmUoInBsb3RfaW1hZ2VzL3BvcF92c19kYW5jZS5wbmciLCBkcGkgPSA3MjAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCmBgYAoKYGBge3J9CnNwb3Rfc2FtcGxlICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBleHBsaWNpdCwgeSA9IHBvcHVsYXJpdHkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC43LCBjb2xvdXIgPSAicmVkNCIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKQpgYGAKCgpNeSBzdHJvbmdlc3QgY29ycmVsYXRpb24gd2FzIHllYXIgKHRoZSB5ZWFyIHRoZSB0cmFjayB3YXMgcmVsZWFzZWQpIHdpdGggYSBjb3JyZWxhdGlvbiBvZiAwLjc0LiBJIHRoZW4gYWRkIHRoaXMgdG8gbXkgbW9kZWwgYXMgbXkgZmlyc3QgZXhwbGFuYXRvcnkgdmFyaWFibGUuCgpgYGB7cn0KbW9kZWxfMWEgPC0gbG0ocG9wdWxhcml0eSB+IHllYXIsCiAgICAgICAgICAgICAgIGRhdGEgPSB0cmFpbl9sbSkKCnN1bW1hcnkobW9kZWxfMWEpCmBgYAoKQWZ0ZXIgcnVubmluZyBteSBtb2RlbCBJJ20gbG9va2luZyBhdCAzIGZhY3RvcnM6CiAtIFRoZSBQLXZhbHVlIC0gaXMgdGhpcyB2YXJpYWJsZSBtYWtpbmcgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlLiBJZiB0aGUgUC12YWx1ZSBpcyBiZWxvdyB0aGUgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUgdGhlbiB3ZSBjYW4gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgYW5kIGNvbmNsdWRlIHRoYXQgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdmFyaWFibGVzIGlzIHNpZ25pZmljYW50CiAKIC0gVGhlIFJeMiAtIGlzIGEgbWVhc3VyZSB0aGF0IGluZGljYXRlcyBob3cgbXVjaCBvZiB0aGUgdmFyaWF0aW9uIG9mIHBvcHVsYXJpdHkgaXMgZXhwbGFpbmVkIGJ5IHRoZSB5ZWFyCiAtIFRoZSBhZGp1c3RlZCBSXjIgLSBjb21wZW5zYXRlcyBmb3IgdGhlIGFkZGl0aW9uIG9mIHZhcmlhYmxlcy4gU28gYXMgd2UncmUgYnVpbGRpbmcgYW4gZXhwbGFuYXRvcnkgbW9kZWwsIHdlIGRvbid0IHdhbnQgdGhpcyB0byBkcm9wIG11Y2ggbG93ZXIgdGhhbiB0aGUgcl4yLgoKYGBge3J9Cm1vZGVsXzNhIDwtIGxtKHBvcHVsYXJpdHkgfiB5ZWFyICsgZGFuY2VhYmlsaXR5ICsgbG91ZG5lc3MsCiAgICAgICAgICAgICAgIGRhdGEgPSB0cmFpbl9sbSkKCnN1bW1hcnkobW9kZWxfM2EpCmBgYAoKYGBge3J9Cm1vZGVsXzNiIDwtIGxtKHBvcHVsYXJpdHkgfiB5ZWFyICsgZGFuY2VhYmlsaXR5ICsgaW5zdHJ1bWVudGFsbmVzcywKICAgICAgICAgICAgICAgZGF0YSA9IHRyYWluX2xtKQoKc3VtbWFyeShtb2RlbF8zYikKYGBgCgpgYGB7cn0KYW5vdmEobW9kZWxfM2EsIG1vZGVsXzJjKQpgYGAKCkZpbmFsIE1vZGVsCgpgYGB7cn0KbW9kZWxfNmEgPC0gbG0ocG9wdWxhcml0eSB+IHllYXIgKyBkYW5jZWFiaWxpdHkgKyBsb3VkbmVzcyArIGxpdmVuZXNzICsgZXhwbGljaXQsCiAgICAgICAgICAgICAgIGRhdGEgPSB0cmFpbl9sbSkKCnN1bW1hcnkobW9kZWxfNmEpCmBgYCAKClNvIGhlcmUgd2UgaGF2ZSBvdXIgZmluYWwgbW9kZWwuIEkgc3RvcHBlZCBhZGRpbmcgdmFyaWFibGVzIGFzIHRoZSBBZGp1c3RlZCByXjIgc3RhcnRlZCBkcm9wcGluZyBhbmQgb3VyIG11bHRpcGxlIHJeMiB3YXMgYmFyZWx5IGdvaW5nIHVwLgoKU28gd2UgY2FuIHNlZSB0aGF0IHRoZSBtb3JlIHJlY2VudCB0aGUgcmVsZWFzZSwgdGhlIG1vcmUgZGFuY2VhYmlsaXR5LCB0aGUgbG91ZGVyIGl0IGlzLCB0aGUgbGVzcyBsaXZlbmVzcyBpdCBoYXMuIFNvIHlvdSBkb24ndCB3YW50IGEgbGl2ZSByZWNvcmRpbmcsIHlvdSB3YW50IGEgc3R1ZGlvIHJlY29yZGluZyB3aXRoIHNvbWUgZXhwbGljaXQgbHlyaWNzIGNodWNrZWQgaW4gdGhlcmUgYXMgd2VsbC4KCkFsbCBvZiBvdXIgUC1WYWx1ZXMgYXJlIHNpZ25pZmljYW50IGFuZCB3ZSBoYXZlIGEgTXVsdGlwbGUgcl4yIG9mIDAuNTUsIHdpdGggYW4gYWRqdXN0ZWQgcl4yIGFsc28gb2YgMC41NS4gVGhpcyBtZWFucyB0aGF0IDU1JSBvZiB0aGUgdmFyaWFuY2UgaW4gcG9wdWxhcml0eSBpcyBleHBsYWluZWQgb3VyIG90aGVyIHZhcmlhYmxlcy4gV2hpY2ggIGFsc28gbWVhbnMgdGhhdCA0NSUgb2YgdGhlIHZhcmlhYmlsaXR5IGluIHRoZSBkYXRhIGNhbm5vdCBiZSBleHBsYWluZWQgYnkgdGhpcyBtb2RlbC4KCjU1JSBpc24ndCBhIHZlcnkgaGlnaCBwcm9wb3J0aW9uIGJ1dCBpdCdzIG5vdCB0ZXJyaWJsZS4gV2UgYXJlIHRyeWluZyB0byBtZWFzdXJlIHRoZSBwb3B1bGFyaXR5IG9mIGEgc29uZy4gSXQncyBub3QgcXVpdGUgYXMgb2J2aW91cyBhcyBpZiB3ZSB3ZXJlIHRyeWluZyB0byBleHBsYWluIHRoZSB2YWx1ZSBvZiBhIGhvdXNlLiBXZSBtaWdodCBmaW5kIHRoYXQgdGhlIHBvc3Rjb2RlIGFuZCB0aGUgbnVtYmVyIG9mIHJvb21zIGdvZXMgYSBsb25nIHdheSB0byBleHBsYWluaW5nIHRoYXQgdmFsdWUuIEkgdGhpbmsgZXhwbGFpbmluZyB0aGUgcG9wdWxhcml0eSBvZiBhIHNvbmcgaXMgYml0IG1vcmUgY29tcGxpY2F0ZWQgdGhhbiB0aGF0LiBJZiBpdCB3YXMgZWFzeSB0byBrbm93IHdoYXQgbWFkZSBhIHNvbmcgcG9wdWxhciB0aGVuIHdlJ2QgYWxsIGJlIG11c2ljaWFucy4KCk1lbnRpb24gaHVtYW4gYmVoYXZpb3VyLCBtZW50aW9uIHRoZSBiYXNpYyBwcmFjdGljZSBvZiBzdGF0aXN0aWNzIHdvdWxkIGNhbGwgdGhpcyBhIG1vZGVyYXRlIGVmZmVjdCBzaXplLiAKCgpgYGB7cn0KbW9kZWxfNmIgPC0gbG0ocG9wdWxhcml0eSB+IHllYXIgKyBkYW5jZWFiaWxpdHkgKyBsb3VkbmVzcyArIGxpdmVuZXNzICsgZXhwbGljaXQsCiAgICAgICAgICAgICAgIGRhdGEgPSB0ZXN0X2xtKQoKc3VtbWFyeShtb2RlbF82YikKCmBgYCAKClNvIG15IG1vZGVsIGlzbid0IGdyZWF0LiBXaGF0IGNhbiBJIGRvIHRvIGltcHJvdmUgdGhpcz8gV2VsbC4uLgoKV2hlbiBJIHdhcyByZXNlYXJjaGluZyBob3cgc3BvdGlmeSBjYWxjdWxhdGUgdGhlaXIgcG9wdWxhcml0eSBzY29yZSBJIGtlcHQgY29taW5nIGFjcm9zcyB0aGlzIG9uZSBwaHJhc2UuCgojIyMgNTAgaXMgdGhlIG1hZ2ljIG51bWJlcgoKVGhlIGhpZ2hlciB5b3VyIHBvcHVsYXJpdHkgaW5kZXgsIHRoZSBtb3JlIGxpa2VseSB0aGUgYWxnb3JpdGhtIGlzIHRvIHJlY29tbWVuZCB5b3UgdG8gbmV3IGxpc3RlbmVycywgYW5kIHBsYWNlIHlvdSBpbiBhbGdvcml0aG1pYyBwbGF5bGlzdHMgbGlrZSBSZWxlYXNlIFJhZGFyIGFuZCBEaXNjb3ZlciBXZWVrbHkuIE1hbnkgd2Vic2l0ZXMgYW5kIGJsb2dzIGhhZCB0aGVvcmllcyBvbiB3aGF0IG51bWJlciB5b3UgaGFkIHRvIGhpdCB0byBiZSBhZGRlZCB0byBjZXJ0YWluIGVkaXRvcmlhbCBwbGF5bGlzdHMuIAoKRElZTXVzaWNpYW4gc3VnZ2VzdHMgdGhhdCBhbmQgcG9wdWxhcml0eSBvZiAyMCsgaW4gdGhlIGZpcnN0IGZldyB3ZWVrcyBvZiByZWxlYXNlIHdpbGwgZ2V0IHlvdSBvbnRvIHRoZSBSZWxlYXNlIFJhZGFyIHBsYXlsaXN0IGFuZCBhIHBvcHVsYXJpdHkgc2NvcmUgb2YgMzArIHdpbGwgZ2V0IHlvdSBvbnRvIERpc2NvdmVyIFdlZWtseS4gTG91ZGxhYiBzdWdnZXN0ZWQgdGhhdCA1MCBpcyB0aGUgbWFnaWMgbnVtYmVyLiBJIGxpa2VkIHRoaXMgaWRlYSBvZiBoYXZpbmcgYSB0aHJlc2hvbGQgb2Ygd2hldGhlciBvciBub3QgYSBzb25nIGlzIHBvcHVsYXIuIFNvIGdvaW5nIGJhY2sgdG8gbXkgdmFyaWFibGVzIEkgY3JlYXRlZCBhIGNvbHVtbiBjYWxsZWQgaXNfcG9wdWxhciB3aGljaCBpcyBvbmx5IFRSVUUgaWYgdGhlIHBvcHVsYXJpdHkgb2YgdGhlIHNvbmcgaXMgNTAgb3Igb3Zlci4gVGhpcyBhbHNvIGxlbmRzIGl0c2VsZiBuaWNlbHkgdG8gYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsLiAKCkxvZ2lzdGljIHJlZ3Jlc3Npb24gaXMgYSBzdGF0aXN0aWNhbCBhbmFseXNpcyBtZXRob2QgdG8gcHJlZGljdCwgb3IgZXhwbGFpbiBhIGJpbmFyeSBvdXRjb21lLCBzdWNoIGFzIHllcyBvciBubywgYmFzZWQgb24gcHJpb3Igb2JzZXJ2YXRpb25zIG9mIGEgZGF0YSBzZXQuCgpTbyByYXRoZXIgdGhhbiB1c2luZyB0aGUgcG9wdWxhcml0eSBzY29yZSBJIGhhdmUgdXNlZCB0aGUgdmFyaWFibGUgSSBjcmVhdGVkIGNhbGxlZCBpc19wb3B1bGFyLCB3aGljaCBzcGxpdHMgdGhlIGRhdGEgaW4gdG8gYSBsb2dpY2FsIHR5cGUsIHNvIGl0J3MgVFJVRSBpZiB0aGUgc29uZyBpcyA1MCBvciBhYm92ZS4KClRoZSB3YXkgdGhpcyBpcyBidWlsdCBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhlIGxpbmVhciBtb2RlbC4gSSBsb29rIGZvciBjb3JyZWxhdGlvbnMsIGFuZCBJIGFkZCB0aGVtIHRvIG15IG1vZGVsIDEgYXQgYSB0aW1lLCBjaGVjayB0aGV5IGFyZSBzaWduaWZpY2FudC4gVGhlIG1haW4gZGlmZmVyZW5jZSBpcyB0aGF0IEknbSBsb29raW5nIGZvciBmb3IgYSBoaWdoIEFVQyBzY29yZSB0aGlzIHRpbWUsIHJhdGhlciB0aGFuIHRoZSBtdWx0aXBsZSByXnNxdWFyZWQgSSB3YXMgbG9va2luZyBmb3IgaW4gdGhlIGxpbmVhciBtb2RlbC4KCkknbGwgZXhwbGFpbiB0aGUgQVVDIGluIGEgc2Vjb25kLiBJIGRlY2lkZWQgZm9yIHRoaXMgbW9kZWwgdG8gbWFrZSBhIGNvdXBsZSBvZiBjaGFuZ2VzLiBJIGRlY2lkZWQgdG8gbm8gbG9uZ2VyIGluY2x1ZGUgdGhlIHllYXIgb3IgZGVjYWRlIHRoZSBzb25nIHdhcyByZWxlYXNlZC4gSWYgSSdtIHN0YXlpbmcgdHJ1ZSB0byBteSBvcmlnaW5hbCBxdWVzdGlvbiB0aGVuIGhvdyBjb3VsZCBJIHBvc3NpYmx5IHdyaXRlIGEgc29uZyB0aGF0IHdhcyByZWxlYXNlZCBpbiB0aGUgcGFzdC4gSXQgaGFkIHN1Y2ggYSBsYXJnZSBpbmZsdWVuY2Ugb24gdGhlIGxpbmVhciBtb2RlbCBJIHRob3VnaHQgaXQgd291bGQgYmUgbW9yZSBpbnRlcmVzdGluZyB0byBzZWUgaG93IHRoZSBsb2dpc3RpYyBtb2RlbCBmYXJlZCB3aXRob3V0IGl0LiBBbmQgdGhlbiBJIGNhbiB0ZXN0IG15IG1vZGVsIGFnYWluc3QgZGlmZmVyZW50IGRlY2FkZXMgdG8gc2VlIGhvdyBpdCBwZXJmb3Jtcy4KCgpPc2NhciBXaWxkZSBpcyBmYW1vdXNseSBjcmVkaXRlZCB3aXRoIGhhdmluZyB3cml0dGVuOiDigJxQb3B1bGFyaXR5IGlzIHRoZSBvbmUgaW5zdWx0IEkgaGF2ZSBuZXZlciBzdWZmZXJlZC7igJ0KCmBgYHtyfQpzcG90X3NhbXBsZSAlPiUgCiAgbXV0YXRlKGV4cGxpY2l0ID0gYXMubG9naWNhbChleHBsaWNpdCkpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBsb3VkbmVzcywgeSA9IHBvcHVsYXJpdHksIGNvbG91ciA9IGV4cGxpY2l0KSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsKICBsYWJzKHggPSAiTG91ZG5lc3MiLAogICAgICAgeSA9ICJQb3B1bGFyaXR5IiwKICAgICAgIHRpdGxlID0gIlJlbGF0aW9uc2hpcCBiZXR3ZWVuIFBvcHVsYXJpdHkgYW5kIExvdW5kZXNzIiwKICAgICAgIHN1YnRpdGxlID0gIkdyb3VwZWQgYnkgZXhwbGljaXQgb3Igbm90IikgKwogICAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gICJEYXJrMiIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNSwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgYXhpcy50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMCwgZmFtaWx5ID0gIlRpbWVzIikKICApIApgYGAKCgpgYGB7cn0Kc3BvdF9zYW1wbGUgJT4lIAogIG11dGF0ZShleHBsaWNpdCA9IGFzLmxvZ2ljYWwoZXhwbGljaXQpKSAlPiUKZ2dwbG90KCkgKwogIGFlcyh4ID0gbG91ZG5lc3MsIHkgPSBhcy5pbnRlZ2VyKGlzX3BvcHVsYXIpLCBjb2xvdXIgPSBleHBsaWNpdCkgKwogIGdlb21faml0dGVyKHNoYXBlID0gMSwKICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMC4wNSwgdyA9IDAuMDUpLAogICAgICAgICAgICAgIGFscGhhID0gMC44KSArCiAgIGdlb21fbGluZShkYXRhID0gdHJhaW5fbW9kZWxfMV9sb3VkLCBhZXMoeCA9IGxvdWRuZXNzICwgeSA9IHByZWQpLCBjb2wgPSAncmVkJykgKwogIHlsYWIoIlByb2JhYmlsaXR5IikgKwogICAgICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAgIkRhcmsyIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNSwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEwLCBmYW1pbHkgPSAiVGltZXMiKQogICkgCgoKIyBnZ3Bsb3QobW9ydGdhZ2VfZGF0YSkgKwojICAgZ2VvbV9qaXR0ZXIoYWVzKHggPSB0dV9zY29yZSwgeSA9IGFzLmludGVnZXIoYWNjZXB0ZWQpKSwgc2hhcGUgPSAxLCAKIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKGggPSAwLjAzKSkgKyAKIyAgICBnZW9tX2xpbmUoZGF0YSA9IHByZWRpY3RfbG9nLCBhZXMoeCA9IHR1X3Njb3JlICwgeSA9IHByZWQpLCBjb2wgPSAncmVkJykgKyAKIyAgIHlsYWIoIlByb2JhYmlsaXR5IikKYGBgCgoKRmluYWwgTG9naXN0aWMgUmVncmVzc2lvbiBNb2RlbApgYGB7cn0KbW9kZWxfNF9maW5hbCA8LSBnbG0oaXNfcG9wdWxhciB+IGxvdWRuZXNzICsgZXhwbGljaXQgKyBkYW5jZWFiaWxpdHkgKyBub19vZl9hcnRpc3RzLAogICAgICAgICAgICAgZmFtaWx5ID0gImJpbm9taWFsIiwKICAgICAgICAgICAgIGRhdGEgPSB0cmFpbl9sb2dfbW9kKQoKc3VtbWFyeShtb2RlbF80X2ZpbmFsKQoKdGlkeShtb2RlbF80X2ZpbmFsKQoKdHJhaW5fbW9kZWxfNF9maW5hbCA8LSB0cmFpbl9sb2dfbW9kICU+JQogIGFkZF9wcmVkaWN0aW9ucyhtb2RlbF80X2ZpbmFsLCB0eXBlID0gInJlc3BvbnNlIikKCnJvY19vYmpfbW9kNCA8LSB0cmFpbl9tb2RlbF80X2ZpbmFsICU+JQogIHJvYyhyZXNwb25zZSA9IGlzX3BvcHVsYXIsIHByZWRpY3RvciA9IHByZWQpCgpyb2NfY3VydmUgPC0gZ2dyb2MoCiAgZGF0YSA9IGxpc3QoCiAgICBiZXN0X21vZGVsID0gcm9jX29ial9tb2Q0CiAgKSwgCiAgbGVnYWN5LmF4ZXMgPSBUUlVFKSArCiAgY29vcmRfZml4ZWQoKSArIAogIHRoZW1lX2NsYXNzaWMoKQoKYXVjKHJvY19vYmpfbW9kNCkKYGBgCgoKYGBge3J9CmxvZ19tb2RfMTk5MCA8LSB0cmFpbl9sb2dfbW9kICU+JSAKICBmaWx0ZXIoZGVjYWRlID09IDE5OTAgfAogICAgICAgICAgIGRlY2FkZSA9PSAyMDAwIHwKICAgICAgICAgICBkZWNhZGUgPT0gMjAxMCkKCm1vZGVsXzkwXzAwXzEwIDwtIGdsbShpc19wb3B1bGFyIH4gbG91ZG5lc3MgKyBleHBsaWNpdCArIGRhbmNlYWJpbGl0eSArIG5vX29mX2FydGlzdHMsCiAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSAiYmlub21pYWwiLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGxvZ19tb2RfMTk5MCkKCnN1bW1hcnkobW9kZWxfOTBfMDBfMTApCgp0aWR5KG1vZGVsXzkwXzAwXzEwKQoKdHJhaW5fbW9kZWxfOTBfMDBfMTAgPC0gbG9nX21vZF8xOTkwICU+JQogIGFkZF9wcmVkaWN0aW9ucyhtb2RlbF85MF8wMF8xMCwgdHlwZSA9ICJyZXNwb25zZSIpCgpyb2Nfb2JqX21vZF85MF8wMF8xMCA8LSB0cmFpbl9tb2RlbF85MF8wMF8xMCAlPiUKICByb2MocmVzcG9uc2UgPSBpc19wb3B1bGFyLCBwcmVkaWN0b3IgPSBwcmVkKQoKCnJvY19jdXJ2ZSA8LSBnZ3JvYygKICBkYXRhID0gbGlzdCgKICAgIGJlc3RfbW9kZWwgPSByb2Nfb2JqX21vZDQsCiAgICBkZWNfNjBzXzcwc184MHMgPSByb2Nfb2JqX21vZF82MF83MF84MCwKICAgIGRlY185MHNfMDBzXzEwcyA9IHJvY19vYmpfbW9kXzkwXzAwXzEwCiAgKSwgCiAgbGVnYWN5LmF4ZXMgPSBUUlVFLAogIGxpbmV3aWR0aCA9IDIpICsKICBjb29yZF9maXhlZCgpICsKICBsYWJzKHggPSAiMSAtIFNwZWNpZmljaXR5IiwKICAgICAgIHkgPSAiU2Vuc2l0aXZpdHkiKSArCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gICJEYXJrMiIpICsKICBzY2FsZV9jb2xvdXJfZGlzY3JldGUobGFiZWxzID0gYygiRmluYWwgTW9kZWwiLCAiNjBzLCA3MHMgJiA4MHMiLCAiOTBzLCAwMHMgJiAxMHMiKSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0ICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIGF4aXMudGl0bGUgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgICNsZWdlbmQudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICAgICAgICAjbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKQogICkKCmF1Yyhyb2Nfb2JqX21vZF85MF8wMF8xMCkKCnJvY19jdXJ2ZQoKZ2dzYXZlKCJwbG90X2ltYWdlcy9sb2dfbW9kZWxzLnBuZyIsIGRwaSA9IDcyMCwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gNikKCmBgYAoKCmBgYHtyfQoKbG9nX21vZF8xOTkwIDwtIHRyYWluX2xvZ19tb2QgJT4lIAogIGZpbHRlcihkZWNhZGUgPT0gMTk5MCB8CiAgICAgICAgICAgZGVjYWRlID09IDIwMDAgfAogICAgICAgICAgIGRlY2FkZSA9PSAyMDEwKQoKbW9kZWxfOTBfMDBfMTAgPC0gZ2xtKGlzX3BvcHVsYXIgfiBsb3VkbmVzcyArIGV4cGxpY2l0ICsgZGFuY2VhYmlsaXR5ICsgbm9fb2ZfYXJ0aXN0cywKICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9ICJiaW5vbWlhbCIsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gbG9nX21vZF8xOTkwKQoKc3VtbWFyeShtb2RlbF85MF8wMF8xMCkKCnRpZHkobW9kZWxfOTBfMDBfMTApCgp0cmFpbl9tb2RlbF85MF8wMF8xMCA8LSBsb2dfbW9kXzE5OTAgJT4lCiAgYWRkX3ByZWRpY3Rpb25zKG1vZGVsXzkwXzAwXzEwLCB0eXBlID0gInJlc3BvbnNlIikKCnJvY19vYmpfbW9kXzkwXzAwXzEwIDwtIHRyYWluX21vZGVsXzkwXzAwXzEwICU+JQogIHJvYyhyZXNwb25zZSA9IGlzX3BvcHVsYXIsIHByZWRpY3RvciA9IHByZWQpCgoKcm9jX2N1cnZlIDwtIGdncm9jKAogIGRhdGEgPSBsaXN0KAogICAgYmVzdF9tb2RlbCA9IHJvY19vYmpfbW9kNAogICksIAogIGxlZ2FjeS5heGVzID0gVFJVRSwKICBsaW5ld2lkdGggPSAyKSArCiAgY29vcmRfZml4ZWQoKSArCiAgbGFicyh4ID0gIjEgLSBTcGVjaWZpY2l0eSIsCiAgICAgICB5ID0gIlNlbnNpdGl2aXR5IikgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICAiRGFyazIiKSArCiAgc2NhbGVfY29sb3VyX2Rpc2NyZXRlKGxhYmVscyA9ICJGaW5hbCBNb2RlbCIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dCAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE4LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBheGlzLnRpdGxlICA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGZhbWlseSA9ICJUaW1lcyIpLAogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxOCwgZmFtaWx5ID0gIlRpbWVzIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE2LCBmYW1pbHkgPSAiVGltZXMiKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApCgphdWMocm9jX29ial9tb2RfOTBfMDBfMTApCgpyb2NfY3VydmUKCmdnc2F2ZSgicGxvdF9pbWFnZXMvbG9nX2Jlc3RfbW9kZWwucG5nIiwgZHBpID0gNzIwLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA2KQoKYGBgCgoKCgo=